#include "LuaAnimation.h"
#include "ggesprite.h"
#include "ggetexture.h"

LuaAnimation::LuaAnimation(){
	m_ani		= gge::Animation_Create();
	m_Filter	= gge::BLEND_NOTEXFILTER;
	m_loop		= gge::ANI_NOLOOP;
	m_AlphaAdd	= 0;
	m_hotx		= 0;
	m_hoty		= 0;
	m_rotation	= 0;
	m_hscale	= 1;
	m_vscale	= 1;
	m_stretchw	= 0;
	m_stretchh	= 0;
}
LuaAnimation::~LuaAnimation(){
	GGE_RELEASE(m_ani);
}
void LuaAnimation::SetTexture(void* texture, int frames, float width, float height){
	gge::ggeTexture *tex = (gge::ggeTexture *)texture;
	m_ani->SetSpeed(5);
	float tx = 0;
	float ty = 0;
	for (int i = 0; i < frames; i++)
	{
		gge::ggeSprite *spr = gge::Sprite_Create(tex, tx, ty, width, height);
		m_ani->AddFrameSprite(spr);
		GGE_RELEASE(spr);

		tx += width;
		if (tx + width > tex->GetWidth(true))
		{
			tx = 0;
			ty += height;
		}
	}
}
void* LuaAnimation::Clone(){
	return m_ani->Clone();
}
void LuaAnimation::Play(){
	m_ani->Play();
}
void LuaAnimation::Stop(){
	m_ani->Stop();
}
void LuaAnimation::Resume() {
	m_ani->Resume();
}
void LuaAnimation::Update(float dt) {
	m_ani->Update(dt);
}
bool LuaAnimation::IsPlaying(){
	return m_ani->IsPlaying();
}
void LuaAnimation::SetMode(int mode) {
	//m_mode = mode;
	m_ani->SetMode( mode|m_loop);
}
int LuaAnimation::GetMode(){
	return m_ani->GetMode();
}
void LuaAnimation::SetSpeed(int v) {
	m_ani->SetSpeed(v);
}
int LuaAnimation::GetSpeed(){
	return m_ani->GetSpeed();
}
void LuaAnimation::SetFrame(int v) {
	m_ani->SetFrame(v);
}
int LuaAnimation::GetFrame(){
	return m_ani->GetFrame();
}
void LuaAnimation::Render2(float x, float y) {
	m_x = x-m_hotx;m_y = y-m_hoty;
	if (m_rotation || m_hscale!=1 || m_vscale!=1)
		m_ani->RenderEx(m_x,m_y,m_rotation,m_hscale,m_vscale );
	else if (m_stretchw || m_stretchh)
		m_ani->RenderStretch(m_x,m_y,m_x+m_stretchw,m_y+m_stretchh);
	else{
		m_ani->Render(m_x,m_y);
		if (m_AlphaAdd)
		{
			gge::ggeSprite* spr = m_ani->GetFrameSprite(m_ani->GetFrame());
			spr->SetBlendMode(spr->GetBlendMode()|gge::BLEND_ALPHAADD);
			spr->SetColor(m_AlphaAdd);
			spr->Render(m_x,m_y);
			spr->SetBlendMode(spr->GetBlendMode()^gge::BLEND_ALPHAADD);
			spr->SetColor(0xffffffff);
		}
	}
}
void LuaAnimation::Render(float x, float y) {
	m_ani->Render(x-m_hotx,y-m_hoty);
}
void LuaAnimation::RenderEx(float x, float y, float rotation, float hscale, float vscale ) {
	m_ani->RenderEx(x-m_hotx,y-m_hoty,rotation,hscale,vscale );
}
void LuaAnimation::RenderStretch(float x1, float y1, float x2, float y2) {
	m_ani->RenderStretch(x1,y1,x2,y2 );
}
void LuaAnimation::Render4V(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3) {
	m_ani->Render4V(x0,y0,x1,y1,x2,y2,x3,y3 );
}
void LuaAnimation::AddFrameSprite(void* spr,int n) {
	m_ani->AddFrameSprite( (gge::ggeSprite *)spr,n);
}
void* LuaAnimation::GetFrameSprite(int n) {
	if (n>=0 && n<m_ani->GetFrameCount())
	{
		gge::ggeSprite* spr = m_ani->GetFrameSprite(n);
		spr->AddRef();
		return spr;
	}
	return NULL;
}
void LuaAnimation::DelFrameSprite(int n) {
	m_ani->DelFrameSprite(n);
}
int LuaAnimation::GetFrameCount() {
	return m_ani->GetFrameCount();
}
float LuaAnimation::GetWidth() {
	return m_ani->GetWidth();
}
float LuaAnimation::GetHeight() {
	return m_ani->GetHeight();
}
void LuaAnimation::GetBoundingBox(void* rect){
	if (m_rotation || m_hscale!=1 || m_vscale!=1)
		m_ani->GetBoundingBoxEx((gge::ggeRect*)rect,m_x,m_y,m_rotation,m_hscale,m_vscale);
	else
		m_ani->GetBoundingBox((gge::ggeRect*)rect,m_x,m_y);
}
void LuaAnimation::GetBoundingBoxEx(void* rect){
	m_ani->GetBoundingBoxEx((gge::ggeRect*)rect,m_x,m_y,m_rotation,m_hscale,m_vscale);
}

bool LuaAnimation::Release(){
	if (m_ani->GetRefCount()==1){
		m_ani->Release();
		m_ani = NULL;
		return true;
	}
	m_ani->Release();
	return false;
}
//===================================================================
void   LuaAnimation::SetColor(UINT color, int i) {
	for (int n=0;n<m_ani->GetFrameCount();n++)
	{
		m_ani->GetFrameSprite(n)->SetColor(color,i);
	}
}
void   LuaAnimation::SetZ(float z, int i){
	for (int n=0;n<m_ani->GetFrameCount();n++)
	{
		m_ani->GetFrameSprite(n)->SetZ(z,i);
	}
}
void   LuaAnimation::SetBlendMode(int blend){
	for (int n=0;n<m_ani->GetFrameCount();n++)
	{
		m_ani->GetFrameSprite(n)->SetBlendMode(blend);
	}
}
void   LuaAnimation::SetHotSpot(float x, float y){
	m_hotx = x;
	m_hoty = y;
}
void   LuaAnimation::SetFlip(bool bX, bool bY, bool bHotSpot){
	for (int n=0;n<m_ani->GetFrameCount();n++)
	{
		m_ani->GetFrameSprite(n)->SetFlip(bX,bY,bHotSpot);
	}
}

UINT   LuaAnimation::GetColor(int i) {
	return m_ani->GetFrameSprite(0)->GetColor(i);
}
float  LuaAnimation::GetZ(int i) {
	return m_ani->GetFrameSprite(0)->GetZ(i);
}
int    LuaAnimation::GetBlendMode(){
	return m_ani->GetFrameSprite(0)->GetBlendMode();
}
float  LuaAnimation::GetHotSpot(lua_State *L){
	lua_pushnumber(L,m_hotx);
	return m_hoty;
}
bool   LuaAnimation::GetFlip(lua_State *L){
	bool bX,bY;
	m_ani->GetFrameSprite(0)->GetFlip(&bX,&bY);
	lua_pushboolean(L,bX);
	return bY;
}
int REG_GGE_Animation(lua_State * L){
	const char* gname = "__ggeAnimation";
	ELuna::registerClass<LuaAnimation>(L, gname,  ELuna::constructor<LuaAnimation>);

	//ELuna::registerMethod<LuaAnimation>(L, "Copy", &LuaAnimation::Copy);
	ELuna::registerMethod<LuaAnimation>(L, "Clone", 			&LuaAnimation::Clone);
	ELuna::registerMethod<LuaAnimation>(L, "Play", 				&LuaAnimation::Play);
	ELuna::registerMethod<LuaAnimation>(L, "Stop", 				&LuaAnimation::Stop);
	ELuna::registerMethod<LuaAnimation>(L, "Resume", 			&LuaAnimation::Resume);
	ELuna::registerMethod<LuaAnimation>(L, "Update", 			&LuaAnimation::Update);
	ELuna::registerMethod<LuaAnimation>(L, "IsPlaying", 		&LuaAnimation::IsPlaying);
	ELuna::registerMethod<LuaAnimation>(L, "SetMode", 			&LuaAnimation::SetMode);
	ELuna::registerMethod<LuaAnimation>(L, "SetSpeed", 			&LuaAnimation::SetSpeed);
	ELuna::registerMethod<LuaAnimation>(L, "SetFrame", 			&LuaAnimation::SetFrame);

	ELuna::registerMethod<LuaAnimation>(L, "GetMode", 			&LuaAnimation::GetMode);
	ELuna::registerMethod<LuaAnimation>(L, "GetSpeed", 			&LuaAnimation::GetSpeed);
	ELuna::registerMethod<LuaAnimation>(L, "GetFrame", 			&LuaAnimation::GetFrame);

	ELuna::registerMethod<LuaAnimation>(L, "Render2", 			&LuaAnimation::Render2);
	ELuna::registerMethod<LuaAnimation>(L, "Render", 			&LuaAnimation::Render);
	ELuna::registerMethod<LuaAnimation>(L, "RenderEx", 			&LuaAnimation::RenderEx);
	ELuna::registerMethod<LuaAnimation>(L, "RenderStretch", 	&LuaAnimation::RenderStretch);
	ELuna::registerMethod<LuaAnimation>(L, "Render4V", 			&LuaAnimation::Render4V);
	ELuna::registerMethod<LuaAnimation>(L, "AddFrameSprite", 	&LuaAnimation::AddFrameSprite);
	ELuna::registerMethod<LuaAnimation>(L, "GetFrameSprite", 	&LuaAnimation::GetFrameSprite);
	ELuna::registerMethod<LuaAnimation>(L, "DelFrameSprite", 	&LuaAnimation::DelFrameSprite);
	ELuna::registerMethod<LuaAnimation>(L, "GetFrameCount", 	&LuaAnimation::GetFrameCount);
	ELuna::registerMethod<LuaAnimation>(L, "GetWidth", 			&LuaAnimation::GetWidth);
	ELuna::registerMethod<LuaAnimation>(L, "GetHeight", 		&LuaAnimation::GetHeight);
	ELuna::registerMethod<LuaAnimation>(L, "GetBoundingBox", 	&LuaAnimation::GetBoundingBox);
	ELuna::registerMethod<LuaAnimation>(L, "GetBoundingBoxEx",	&LuaAnimation::GetBoundingBoxEx);
	ELuna::registerMethod<LuaAnimation>(L, "SetTexture",		&LuaAnimation::SetTexture);

	ELuna::registerMethod<LuaAnimation>(L, "SetP",				&LuaAnimation::SetP);
	ELuna::registerMethod<LuaAnimation>(L, "GetP",				&LuaAnimation::GetP);
	ELuna::registerMethod<LuaAnimation>(L, "Release",			&LuaAnimation::Release);
	ELuna::registerMethod<LuaAnimation>(L, "AddRef",			&LuaAnimation::AddRef);
	ELuna::registerMethod<LuaAnimation>(L, "GetRefCount",		&LuaAnimation::GetRefCount);

	ELuna::registerMethod<LuaAnimation>(L, "SetColor",			&LuaAnimation::SetColor);
	ELuna::registerMethod<LuaAnimation>(L, "SetZ",				&LuaAnimation::SetZ);
	ELuna::registerMethod<LuaAnimation>(L, "SetBlendMode",		&LuaAnimation::SetBlendMode);
	ELuna::registerMethod<LuaAnimation>(L, "SetHotSpot",		&LuaAnimation::SetHotSpot);
	ELuna::registerMethod<LuaAnimation>(L, "SetFlip",			&LuaAnimation::SetFlip);

	ELuna::registerMethod<LuaAnimation>(L, "GetColor",			&LuaAnimation::GetColor);
	ELuna::registerMethod<LuaAnimation>(L, "GetZ",				&LuaAnimation::GetZ);
	ELuna::registerMethod<LuaAnimation>(L, "GetBlendMode",		&LuaAnimation::GetBlendMode);
	ELuna::registerMethod<LuaAnimation>(L, "GetHotSpot",		&LuaAnimation::GetHotSpot,2);
	ELuna::registerMethod<LuaAnimation>(L, "GetFlip",			&LuaAnimation::GetFlip,2);

	ELuna::registerMethod<LuaAnimation>(L, "SetRotation",		&LuaAnimation::SetRotation);
	ELuna::registerMethod<LuaAnimation>(L, "SetScale",			&LuaAnimation::SetScale);
	ELuna::registerMethod<LuaAnimation>(L, "SetStretch",		&LuaAnimation::SetStretch);
	ELuna::registerMethod<LuaAnimation>(L, "SetTextureFilter",	&LuaAnimation::SetTextureFilter);
	ELuna::registerMethod<LuaAnimation>(L, "IsTextureFilter",	&LuaAnimation::IsTextureFilter);
	ELuna::registerMethod<LuaAnimation>(L, "SetAlphaAdd",		&LuaAnimation::SetAlphaAdd);
	ELuna::registerMethod<LuaAnimation>(L, "IsAlphaAdd",		&LuaAnimation::IsAlphaAdd);
	ELuna::registerMethod<LuaAnimation>(L, "GetRotation",		&LuaAnimation::GetRotation);
	ELuna::registerMethod<LuaAnimation>(L, "GetScale",			&LuaAnimation::GetScale,2);
	ELuna::registerMethod<LuaAnimation>(L, "GetStretch",		&LuaAnimation::GetStretch,2);

	ELuna::registerMethod<LuaAnimation>(L, "SetLoop",			&LuaAnimation::SetLoop);
	ELuna::registerMethod<LuaAnimation>(L, "IsLoop",			&LuaAnimation::IsLoop);
	return 1;
}